package com.jinyu.common.exception.handler;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import com.jinyu.common.base.ApiRestResponse;
import com.jinyu.common.enums.ApiRestCodeEnum;
import com.jinyu.common.exception.BaseRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLException;
import java.util.Objects;

/**
 * @Author: yangli
 * @Despriction: 全局异常处理 - 处理过程从上往下进行校验,一旦被校验则不再继续往下执行
 * @Package: com.jinyu.common.exception.handler
 * @Date:Created in 2022/5/1 23:12
 * @Modify By:
 */
@RestControllerAdvice
@Slf4j
@ResponseBody
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {NotLoginException.class})
    public ApiRestResponse<String> notLoginExceptionHandler(NotLoginException e) {
        log.error("账号异常:", e);
        String type = e.getType();
        String msg = switch (type) {
            case NotLoginException.INVALID_TOKEN -> "账号异常：无效token";
            case NotLoginException.TOKEN_TIMEOUT, NotLoginException.BE_REPLACED, NotLoginException.KICK_OUT ->
                    "账号异常：您已掉线";
            default -> "账号异常：未能从请求中读取到token";
        };

        return ApiRestResponse.err(ApiRestCodeEnum.FAIL_NOT_LOGIN.getCode(),msg + "，请刷新页面重新登录");
    }

    @ExceptionHandler(value = {NotPermissionException.class})
    public ApiRestResponse<String> notPermissionExceptionHandler(NotPermissionException e) {
        log.error("缺乏操作权限:", e);
        return ApiRestResponse.err("缺乏操作权限:" + e.getMessage());
    }

    @ExceptionHandler(value = {NotRoleException.class})
    public ApiRestResponse<String> notRoleExceptionHandler(NotRoleException e) {
        log.error("缺乏角色权限:", e);
        return ApiRestResponse.err("缺乏角色权限:" + e.getMessage());
    }

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public ApiRestResponse<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("参数校验失败:", e);
        BindingResult bindingResult = e.getBindingResult();
        return ApiRestResponse.err("参数校验失败:" + Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    }

    @ExceptionHandler(value = {SQLException.class})
    public ApiRestResponse<String> SQLExceptionHandler(SQLException e) {
        log.error("数据库异常:", e);
        return ApiRestResponse.err("数据库异常,请联系管理员处理:" + e.getMessage());
    }

    @ExceptionHandler(value = {BaseRuntimeException.class})
    public ApiRestResponse<String> baseRuntimeExceptionHandler(BaseRuntimeException e) {
        log.error("自定义异常:", e);
        return ApiRestResponse.err(e.getMessage());
    }

    @ExceptionHandler(value = {Exception.class})
    public ApiRestResponse<String> globalExceptionHandler(Exception e) {
        log.error("未知异常:", e);
        return ApiRestResponse.err("系统错误，请联系管理员处理:" + e.getMessage());
    }

}
